import pandas as pd
from io import StringIO

# 某员工一段时间上班打卡的时间记录如下，现在需要计算他在这期间的平均打卡时间。
# 一周打卡时间记录
ts = '''
2020-10-28 09:59:44
2020-10-29 10:01:32
2020-10-30 10:04:27
2020-11-02 09:55:43
2020-11-03 10:05:03
2020-11-04 09:44:34
2020-11-05 10:10:32
2020-11-06 10:02:37
'''

# 读取数据，类型设置为时间类型
df = pd.read_csv(StringIO(ts), names=["time"], parse_dates=["time"])  # parse_dates：默认解析为相应类型
print(df)

# 对时间序列求平均
print(df["time"].mean())  # 2020-11-02 04:00:31.500000
"""
我们发现，mean 方法会对时间序列的时间戳求平均值，得出的值为 11 月 2 日凌晨 4点，
这和我们的需求不符，因为我们不需要关心具体是哪天，只关注时间。

正确的做法是将日期归到同一天，再求平均时间。
时间的 replace 方法可以实现这个功能，结合函数的调用方法，
有以下三种办法可以实现同样的效果：
"""
t1 = df["time"].apply(lambda s: s.replace(year=2023, month=7, day=21)).mean()
t2 = df["time"].apply(pd.Timestamp.replace, year=2023, month=7, day=21).mean()
t3 = df["time"].agg(pd.Timestamp.replace, year=2023, month=7, day=21).mean()

"""
前两个方法都用 apply 来调用时间的 replace 方法，
    第一个用 lambda 来调用，
    第二个直接用 Pandas 的固定时间对象来调用，
第三个方法用 agg 来调用函数。

将时间的日期归到同一天后，再用 mean 求得平均时间为 10:00:31，就得到了该员工平均的打卡时间。
"""

print(t1)
print(t2)
print(t3)
